home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / ww_tv.exe / WRAP.ASM < prev   
Assembly Source File  |  1992-02-11  |  23KB  |  805 lines

  1. ;/**************************************************************************/
  2. ;/*                                                                        */
  3. ;/*                   Copyright (c) 1991 Primatech Inc.                    */
  4. ;/*                                                                        */
  5. ;/*                          All Rights Reserved                           */
  6. ;/*                                                                        */
  7. ;/**************************************************************************/
  8.  
  9. ;/*------------------------------------------------------------*/
  10. ;/* filename -       wrap.asm                                  */
  11. ;/*                                                            */
  12. ;/* function(s)                                                */
  13. ;/*                  TEditor::doWordWrapBuffer                 */
  14. ;/*------------------------------------------------------------*/
  15.  
  16. ;Created:       12 November 1991 by Jeffrey A. Hottle
  17.  
  18.  
  19.     IDEAL
  20.     JUMPS
  21.     MODEL LARGE, PROLOG
  22.  
  23.     INCLUDE "TVWRITE.INC"
  24.  
  25.     PUBLIC @TEditor@doWordWrapBuffer$qususns
  26.  
  27.     EXTRN @TEditor@changeBufSize$qs:PROC
  28.  
  29.     CR = 0Dh
  30.     LF = 0Ah
  31.  
  32. CODESEG
  33.  
  34. MACRO AdvancePtr
  35. LOCAL @@OK
  36.     inc  BX
  37.     cmp  BX,[ES:DI+TEditorCurPtr]
  38.     jne  @@OK
  39.     add  BX,[ES:DI+TEditorGapLen]
  40. @@OK:
  41. ENDM
  42.  
  43.  
  44.  
  45. ;ushort TEditor::doWordWrapBuffer( ushort start_ofs,
  46. ;                                  ushort min_chars,
  47. ;                                  int* line_delta )
  48. ;assume:
  49. ;   line_delta is initialized
  50. ;   start_ofs is beginning of a line
  51. ;   at least 2 lines or min_chars will be processed
  52. ;
  53. PROC @TEditor@doWordWrapBuffer$qususns
  54.  
  55.     ARG   thisPtr:FAR PTR, StartOfs:WORD, MinChars:WORD, LineDelta:PTR WORD
  56.     USES  DS,SI,DI
  57.     LOCAL Delta:WORD, CharCt:WORD, LineCt:WORD, RealDS:WORD
  58.     LOCAL BufChg:BYTE, LineChg:BYTE, LineStart:WORD, DelLastCR:BYTE
  59.     LOCAL WrapPos:WORD, WrapDX:WORD, WrapCharCt:WORD
  60.  
  61.     ASSUME DS:nothing, ES:nothing
  62.  
  63.     xor  AX,AX
  64.     mov  [Delta],AX
  65.     mov  [CharCt],AX
  66.     mov  [LineCt],AX
  67.     mov  [BufChg],AL
  68.  
  69.     mov  [RealDS],DS              ;save original DATASEG
  70.  
  71.     les  DI,[thisPtr]
  72.     lds  SI,[ES:DI+TEditorBuffer] ;DS:SI = buffer
  73.     mov  BX,[StartOfs]
  74.  
  75.     ; update BX if it is sitting at the start of the gap
  76.     cmp  BX,[ES:DI+TEditorCurPtr]
  77.     jne  ScanLine
  78.     add  BX,[ES:DI+TEditorGapLen]
  79.  
  80. ScanLine:
  81.     ;----------------------------------
  82.     ; scan to find line break position
  83.     ;----------------------------------
  84.     xor  DX,DX                    ;DH = CR count, DL = previous buffer char
  85.     xor  CX,CX                    ;CX = current x position
  86.     cld
  87.     xor  AX,AX
  88.     mov  [LineChg],AL
  89.     mov  [DelLastCR],AL
  90.     mov  [WrapPos],AX
  91.     mov  [LineStart],BX
  92.     jmp  short ScanSkip
  93. ScanNext:
  94.     mov  AH,AL                    ;save previous line character
  95.     AdvancePtr                    ;advance pointer
  96. ScanSkip:
  97.     mov  DL,AL                    ;save previous buffer character
  98.     cmp  BX,[ES:DI+TEditorBufSize];check for end of buffer
  99.     jae  BufEnd
  100.     inc  CX                       ;advance column number
  101.     inc  [CharCt]
  102.     mov  AL,[SI+BX]               ;get character from buffer
  103.     cmp  AL,CR                    ;is this character a CR?
  104.     jne  NotCR
  105.     AdvancePtr
  106.     cmp  [BYTE PTR SI+BX],LF      ;yes, is it CR+LF? (hard return)
  107.     jne  JustCR
  108.     AdvancePtr                    ;hard return, skip LF
  109.     inc  [CharCt]
  110.     jmp  DelAllCR                 ;remove all soft returns from this line
  111. JustCR:
  112.     inc  DH                       ;bump soft-return count
  113.     dec  CX                       ;don't count this as a column
  114.     jmp  ScanSkip
  115. NotCR:
  116.     cmp  AL,' '                   ;check for space
  117.     je   ScanNext                 ;skip spaces
  118.     cmp  AL,9                     ;check for tab
  119.     jne  NotSpace
  120.  
  121.     mov  AX,CX                    ;adjust column number to next tab position
  122.     dec  AX
  123.     div  [BYTE PTR ES:DI+TEditorTabSize]  ;AH = # past previous tab stop
  124.     mov  AL,[ES:DI+TEditorTabSize]
  125.     sub  AL,AH
  126.     cbw
  127.     add  CX,AX                    ;CX = column number of next tab stop
  128.     mov  AL,' '
  129.     jmp  ScanNext
  130.  
  131. NotSpace:
  132.     cmp  AH,' '                   ;non-space, check prev for space or hyphen
  133.     je   SetBreak
  134.     cmp  AH,'-'
  135.     je   SetBreak
  136.  
  137.     cmp  CX,[ES:DI+TEditorRMargin];no break here, check if past end of line
  138.     jbe  ScanNext                 ;not past end
  139.  
  140.     cmp  [WrapPos],0              ;past end, have we found a break yet?
  141.     jnz  BreakPos                 ;yes
  142.     jmp  BreakPosGo               ;no, use this position
  143.  
  144. SetBreak:
  145.     mov  [WrapPos],BX
  146.     mov  [WrapDX],DX
  147.     push AX
  148.     mov  AX,[CharCt]
  149.     mov  [WrapCharCt],AX
  150.     pop  AX
  151.     cmp  CX,[ES:DI+TEditorRMargin];is this the end of the line?
  152.     jbe  ScanNext                 ;no
  153.  
  154.     ;---------------------------------------------------------
  155.     ; break position found, check if line already breaks here
  156.     ;---------------------------------------------------------
  157. BreakPos:
  158.     mov  BX,[WrapPos]             ;set current pointer back to wrap position
  159.     mov  DX,[WrapDX]              ;get previous buffer char & CR count
  160.     mov  AX,[WrapCharCt]          ;set proper character count
  161.     mov  [CharCt],AX
  162. BreakPosGo:
  163.     dec  [CharCt]                 ;adjust count for character after the break
  164.     cmp  DH,1                     ;check for 1 CR found
  165.     jne  FixBuffer
  166.     cmp  DL,CR                    ;check if CR is previous char in buffer
  167.     je   NextLine                 ;it is, no change to buffer needed
  168.     jmp  FixBuffer
  169.  
  170.     ;----------------------------------------
  171.     ; end of buffer, remove all soft returns
  172.     ;----------------------------------------
  173. BufEnd:
  174.     or   DH,DH                    ;any soft-returns in this line?
  175.     jz   Success                  ;no, we're done
  176.  
  177.     ;--------------------------------------
  178.     ; remove all soft returns in this line
  179.     ;--------------------------------------
  180. DelAllCR:
  181.     mov  [DelLastCR],1
  182.  
  183.     ;----------------------------------------------------------------
  184.     ; update buffer removing soft returns, setting new one if needed
  185.     ;----------------------------------------------------------------
  186. FixBuffer:
  187.     mov  CX,BX                    ;save ending position
  188.     or   DH,DH                    ;are there any CRs?
  189.     jz   NoCR
  190.     mov  BX,[LineStart]           ;get start-of-line position
  191. FindCR:
  192.     cmp  [BYTE PTR SI+BX],CR      ;is this character a CR?
  193.     je   FoundCR
  194.     AdvancePtr                    ;no, try next character
  195.     jmp  FindCR
  196. FoundCR:
  197.     dec  DH                       ;adjust CR count
  198.     jnz  DeleteIt                 ;not last one yet
  199.     cmp  [DelLastCR],0            ;delete last CR?
  200.     jz   LastCR
  201. DeleteIt:
  202.     dec  [Delta]                  ;adjust line delta value
  203.     mov  [LineChg],1
  204.     mov  [BufChg],1
  205.  
  206.     ; compress text at BX, updating ptr in CX and other object pointers
  207.     call CompressBuf
  208.     or   DH,DH
  209.     jnz  FindCR
  210.  
  211. LastCR:
  212.     ; shift text (if needed) to put CR at end of line
  213.     cmp  [DelLastCR],0            ;do we want a CR on this line?
  214.     jnz  RightPlace               ;no
  215.     cmp  DL,CR                    ;check if we have a CR in the right place
  216.     je   RightPlace
  217.  
  218.     ; shift text at BX thru CX and put CR in the hole
  219.     mov  [LineChg],1
  220.     mov  [BufChg],1
  221.     call ShiftBuf
  222.     mov  BX,CX                    ;put CR in the hole
  223.     mov  [BYTE PTR SI+BX],CR
  224.     AdvancePtr                    ;skip over that location
  225.     jmp  NextLine
  226.  
  227. NoCR:
  228.     cmp  [DelLastCR],0            ;do we want a CR on this line?
  229.     jnz  RightPlace               ;no
  230.  
  231.     ; expand buffer at end and insert CR in hole
  232.     mov  BX,CX
  233.     mov  AX,[RealDS]
  234.     call ExpandBuf
  235.     or   AX,AX                    ;check for expand failure
  236.     jz   Failure
  237.     mov  [LineChg],1
  238.     mov  [BufChg],1
  239.     inc  [Delta]                  ;adjust line delta value
  240.     mov  [BYTE PTR SI+BX],CR
  241.  
  242. RightPlace:
  243.     mo